import asyncio
import time
from textwrap import dedent
from typing import Optional, List

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAILike
from agno.tools.mcp import MCPTools, MultiMCPTools
from configs.basic_config import ALI_GENERATION_MODEL, AGENT_URL, ALI_DASHSCOPE_API_KEY

# MCP服务器URL
url = "http://127.0.0.1:9001/mcp"


async def run_agent(message: Optional[str] = None) -> None:
    """运行基金助手的交互式命令行界面"""
    # urls = [url, url]
    # async with MultiMCPTools(
    #         transport="streamable-http", urls=urls, allow_partial_failure=True,
    # ) as fund_tools:

    async with MCPTools(
            transport="streamable-http", url=url
    ) as fund_tools:
        try:
            today = time.strftime("%Y-%m-%d", time.localtime())
            now = time.strftime("%H:%M:%S", time.localtime())
            session_id = "fund_advisor_session"
            description = f"您是智能基金投资顾问，今日日期 {today}，当前时间 {now}"
            description += f" - 会话ID: {session_id}"

            agent = Agent(
                db=SqliteDb(db_file="tmp/fund_agent.db"),
                tools=[fund_tools],
                description=description,
                tool_choice='auto',
                instructions=dedent(""" \
                    您是智能基金投资顾问，使用MCP工具处理基金数据查询和分析。

                    # 工具使用规则
                    1. 只能使用提供的MCP工具；
                    2. 当用户明确提出要生成报告时调用report.*生成报告；

                    # 工具分类
                    - fund_basic.*: 基金基础信息
                    - fund_manager.*: 基金经理相关  
                    - fund_performance.*: 基金业绩表现
                    - fund_holdings.*: 基金持仓信息
                    - fund_net_value.*: 基金净值信息
                    - report.*: 生成报告

                    # 链式调用策略
                    ## 当缺少参数时：
                    - 可选用fund_basic.match或其他适合的工具 → 获取相关需要参数 -> 然后传递获取的参数给下一步要调用的工具；

                    # 报告生成要求
                    - data: List[Dict] 格式；
                    - 设置合适的title和description；
                    - 必须包含风险提示；

                    # 注意事项
                    - 依据上述工具分类，来选用合适前缀的工具，避免工具乱用；
                    - 你需要根据用户提问获取参数，若你无法从自然语言提取开始日期和截止日期参数，截止日期默认传入今日日期，起始日期传入None；
                    - 保存中间结果用于后续调用；
                    - 如果依据搜索结果不能回答用户问题，直接说明“依据当前信息无法回答”，不要编造答案。
                """),
                markdown=True,
                #add_history_to_context=True,
                session_id=session_id,
                #num_history_runs=10,
                #read_chat_history=True,
                #read_tool_call_history=True,
                debug_mode=True,
                model=OpenAILike(
                    id=ALI_GENERATION_MODEL,
                    name=ALI_GENERATION_MODEL,
                    api_key=ALI_DASHSCOPE_API_KEY,
                    base_url=AGENT_URL,
                    temperature=0.1
                ),
            )

            print("📊 智能基金投资顾问")
            print("工具: fund_basic | fund_manager | fund_performance | fund_holdings | fund_net_value | report")
            print("\n示例问题:")
            print("• 诺安成长混合A(320007)的基本信息")
            print("• 刘慧影经理的管理经验和基金")
            print("• 诺安成长混合近一年的业绩表现")
            print("• 基金前十大重仓股和持仓集中度")
            print("• 2025年Q2到Q3的持仓变动分析")
            print("• 基金风险收益特征和投资风格")
            print("-" * 50)

            await agent.acli_app(message=message, stream=True)
        finally:
            print("会话结束")


if __name__ == "__main__":
    asyncio.run(run_agent(message=None))